/*
 * File:   main.cpp
 * Author: cyril
 *
 * Created on 10 décembre 2012, 09:33
 */
#include <iostream>
#include <stdio.h>
#include <mpi.h>
#include "const.h"
#include <math.h>

using namespace std;

int main(int argc, char* argv []) {
    int compteur, myrank, nombre, pas;
    float epsilon;
    MPI_Comm parent;
    MPI_Status etat;
    MPI_Request request;
    float temperature_moyenne, ancienne_temperature_moyenne,temperature,temperature_calcul;
    MPI_Init(&argc, &argv);
    MPI_Comm_get_parent(&parent);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &nombre);
    if (parent == MPI_COMM_NULL) {
        printf("Fils %d : coord : Pas de pere !\n", myrank);
    } else {
        MPI_Recv(&compteur, 1, MPI_INT, 0, 0, parent, &etat);
        printf("Fils %d : coord : Reception du maitre !\n", myrank);
	ancienne_temperature_moyenne=0;
        // Ecart que l'on souhaite avoir au maximum par raport à la température ambiante
        epsilon = 1;
        // Compteur qui ressemble les processus tant que la temperature des plaques n'est pas celle
        // (ou presque) de la température ambiante
        pas = 1;
        
        // Tant que l'écart est supérieur à l'epsilon, on incrémente le pas
        while (epsilon >= 0.000001) {
		temperature_moyenne=0;
		temperature_calcul=0;
            // Envoi du pas n°1 à tout les calculateurs
            for (int i = 0; i < nombre - 1; i++) {
                MPI_Send(&pas, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
            }
 	
            // Reception de toutes les nouvelles temperatures
            for (int i = 0; i < nombre - 1; i++) {
		               
		MPI_Irecv(&temperature, 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD, &request);
		MPI_Wait(&request, &etat);

		printf("************** Reception temperature %f de %d :  !\n", temperature,i);
		temperature_calcul+=temperature;
            }

            // Calcul de la nouvelle moyenne de la plaque
		temperature_moyenne = temperature_calcul/(nombre - 1);
printf("************** Nouvelle temperature moyenne %f :  !\n", temperature_moyenne);
            // Calcul la différence (epsilon) avec l'ancienne moyenne temperature_moyenne
            epsilon = fabs(ancienne_temperature_moyenne-temperature_moyenne);
		ancienne_temperature_moyenne=temperature_moyenne;
		printf("************** Epsilon %f :  !\n", epsilon);
            pas++;
        }

        
        pas = -1;
        for (int i = 0; i < nombre - 1; i++) {
            MPI_Send(&pas, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
        }
    }

    // Fin MPI
    MPI_Finalize();
    return 0;

}
